﻿namespace FODATAC

open System
open FODATAC.HTTP
open FODATAC.Interfaces
open Microsoft.Data.Edm
open Microsoft.Data.OData
open System.Net

type SessionFactory(baseUri : Uri, user, password) as this = 
    [<DefaultValue>] val mutable private model : IEdmModel
    [<DefaultValue>] val mutable private networkCrediential : NetworkCredential
    [<DefaultValue>] val mutable private metaData : MetaData
    [<DefaultValue>] val mutable private uri : Uri
    do 
        let ensureTrailingSlash (str:string) =
            let length = str.Length
            let lastChar = str.[length-1]
            match lastChar with
            | '/' -> str
            | _ -> str+"/"

        this.uri <- Uri(baseUri.AbsoluteUri |> ensureTrailingSlash)
        this.networkCrediential <- NetworkCredential(user, password)
        let request = HttpWebRequest.CreateHttp(Uri(this.uri,"$metadata"))
        request.Credentials <- this.networkCrediential
        let work = 
            async { 
                let! response = request.AsyncGetResponse()
                use metadataMessage = new ClientHttpResponseMessage(response :?> HttpWebResponse)
                let messageReaderSettings = 
                    ODataMessageReaderSettings(MaxProtocolVersion = ODataVersion.V3, EnableAtomMetadataReading = true, CheckCharacters = false)
                use messageReader = new ODataMessageReader(metadataMessage)
                this.model <- messageReader.ReadMetadataDocument()
                this.metaData <- MetaData(this.model)
            }
        Async.StartAsTask(work).Wait()
    
    interface ISessionFactory with
        member this.MetaData = this.metaData
        member this.NetworkCredential = this.networkCrediential
        member this.OpenSession() : ISession = upcast new Session(this)
        member this.BaseUri = this.uri
